
#include "Debug.h"
#include <sstream>
#include <string>
#include <stdlib.h>
#include <sys/stat.h>
#include <libpq-fe.h>
#include <map>
#include <string.h>
#include <glib.h>
#include "config.h"
#include "define.h"

using namespace std;

extern "C" {
  bool nidConsInit(char *consumer, const char* conf);
  bool nidConsFriends(char *user, GHashTable *frs);
  void nidConsShutdown();
  void nidConsFlush(char *consumer);
};

PGconn *g_db = NULL;

bool nidConsInit(char *consumer, const char* conf)
{
        struct stat st;
        if (lstat(conf, &st) != 0)
        {
                ERRO<<":"<<conf<<" is not exist!"<<endl;
                return false;
        }
        Configure cfg;
        map <string, string > g_Confs;
        g_Confs = cfg.LoadConfInfo(conf);
        cfg.Print();
        if(g_Confs.size() <= 0)
        {
                cerr<<"error to explain conf :"<< conf<<endl;
                return true;
        }
        map <string, string >::iterator iter;
        string dbhost, dbuser, dbpass, dbname;
        if (g_Confs.find("dbhost") != g_Confs.end())
                dbhost = g_Confs["dbhost"];
        if (g_Confs.find("dbuser") != g_Confs.end())
                dbuser = g_Confs["dbuser"];
        if (g_Confs.find("dbpass") != g_Confs.end())
                dbpass = g_Confs["dbpass"];
        if (g_Confs.find("dbname") != g_Confs.end())
		dbname = g_Confs["dbname"];
        string dbport = "5432";
        if (g_Confs.find("dbport") != g_Confs.end())
		dbport = g_Confs["dbport"];

	g_db = PQsetdbLogin(dbhost.c_str(), dbport.c_str(), NULL, NULL, dbname.c_str(), dbuser.c_str(), dbpass.c_str());

	if(PQstatus(g_db) != CONNECTION_OK)
	{
		ERRO << PQerrorMessage(g_db) << endl;
		PQfinish( g_db);
		g_db = NULL;
                return false;
	}

        return true;
}

bool nidConsFriends(char * user,   GHashTable *frs)
{
	if(g_db == NULL)
	{
		cerr<<"db connection is NULL"<<endl;
		return false;
	}
	if(user == NULL)
		return false;

	int u = atoi(user);
	stringstream sql;
	sql <<"select nick from user_profile where id="<<u;
	PGresult *result = PQexec(g_db, sql.str().c_str());
	if(PQresultStatus(result) != PGRES_TUPLES_OK)
	{
		cerr << PQerrorMessage(g_db) << endl;
		PQclear(result);
		return false;
	}
	long rownum = PQntuples(result);
	if (rownum <= 0 )
	{
		PQclear(result);
		return false;
	}

	FObject *uself = new FObject(user, 1,  (char *)PQgetvalue(result, 0, 0) ) ;
	g_hash_table_insert(frs, g_strdup(user), uself);
	PQclear(result);
	sql.str(""); 
	sql<<"select u.partnerid, p.nick from user_relation as u, user_profile as p where ownerid ="<<u<<" and class=1 and u.partnerid=p.id";
	DEBUG1(sql.str());
	result = PQexec(g_db, sql.str().c_str());
	if(PQresultStatus(result) != PGRES_TUPLES_OK)
	{
		cerr << PQerrorMessage(g_db) << endl;
		PQclear(result);
		return false;
	}

	rownum = PQntuples(result);
	DEBUG2("fetch row = ", rownum);
	if (rownum == 0 )
	{
		PQclear(result);
		return true;
	}
	for (int i = 0; i < rownum; i++)
	{
		FObject *uf = new FObject(PQgetvalue(result,i,0), 1,  (char *)PQgetvalue(result, i, 1) ) ;
		g_hash_table_insert(frs, g_strdup(PQgetvalue(result, i, 0)), uf);
	}
	PQclear(result);
	return true;
}

void nidConsShutdown()
{
	if(g_db != NULL){
		PQfinish( g_db);
		g_db = NULL;
	} 
 // Do whatever to close/flush/sync the consumer's work before exit...
  //   delete gx_TxLog;
}

void nidConsFlush(char * consumer)
{
  // If this consumer keeps statistics or writes to a tx log, then
  // flush the statistics here, otherwise do nothing.
}


